using System;
using L=Science.Physics.GeneralPhysics;

namespace Serway.Chapter05
{
	/// <summary>
	/// Example10: Acceleration of Two Objects Connected by a Cord
	/// A ball of mass m_1 and a block of mass m_2 are attached
	/// by a lightweight cord that passes over a frictionless
	/// pulley of negligible mass. The block lies on a frictionless
	/// incline of angle \theta. Find the magnitude of the 
	/// acceleration of the two objects and the tension in the cord.
	/// a = (m_2 g \sin\theta - m_1 g)/(m_1+m_2)
	/// T = m_1 m_2 g (\sin\theta + 1)/(m_1+m_2)
	/// </summary>
	public class Example10
	{
		public Example10()
		{
		}
		private string result;
		public string Result
		{
			get{return result;}
		}
		public void Compute()  
		{
			L.TotalForce[] f = new L.TotalForce[2]; 
			L.Mass[] m = new L.Mass[2];
			L.Acceleration[] a = new L.Acceleration[2];

			double theta = 20.0/180.0*Math.PI;

			m[0]= new L.Mass();
			m[0].kg = 10.0;
			m[1]= new L.Mass();
			m[1].kg = 20.0;
			
			L.Force[] ff = new L.Force[2];
			ff[0] = new L.Force();   // tension
			ff[0].YVariableQ = true; 
			ff[1] = new L.Force();   // gravity
			ff[1].Y = -m[0].kg*L.Constant.AccelerationOfGravity; 

			f[0] = new L.TotalForce(ff);
			
			L.Force[] sf = new L.Force[3];
			sf[0] = new L.Force();  // tension
			sf[0].XVariableQ = true;
			sf[1] = new L.Force();  // gravity
			sf[1].X = m[1].kg*L.Constant.AccelerationOfGravity*Math.Sin(theta);
			sf[1].Y = -m[1].kg*L.Constant.AccelerationOfGravity*Math.Cos(theta);
			sf[2] = new L.Force();  // normal
			sf[2].YVariableQ = true;
		
			f[1] = new L.TotalForce(sf);			
			
			a[0] = new L.Acceleration();
			a[0].YVariableQ = true; 
			a[1] = new L.Acceleration();
			a[1].XVariableQ = true; 

			L.NewtonEquation.ConstraintFunctionToBeZero[] cf
				= new L.NewtonEquation.ConstraintFunctionToBeZero[3];
			cf[0] = new L.NewtonEquation.ConstraintFunctionToBeZero(Min1);
			cf[1] = new L.NewtonEquation.ConstraintFunctionToBeZero(Min2);
			cf[2] = new L.NewtonEquation.ConstraintFunctionToBeZero(Min3);
			
			L.NewtonEquation eq = new L.NewtonEquation(f,m,a);			
			eq.Constraint(cf);

			eq.Solve();
		
			result += Convert.ToString(a[0].Y)+"\r\n";
			result += Convert.ToString(f[0].DecomposedForce[0].N)+"\r\n";
		
			result += Convert.ToString((m[1].kg*Math.Sin(theta)-m[0].kg)/(m[0].kg+m[1].kg)
				*L.Constant.AccelerationOfGravity)+"\r\n";
			result += Convert.ToString(m[1].kg*m[0].kg*(Math.Sin(theta)+1.0)/(m[0].kg+m[1].kg)
				*L.Constant.AccelerationOfGravity)+"\r\n";
		}
		private double Min1(L.TotalForce[] f, L.Mass[] m, L.Acceleration[] a)
		{
			return f[0].DecomposedForce[0].Y + f[1].DecomposedForce[0].X;
		}
		private double Min2(L.TotalForce[] f, L.Mass[] m, L.Acceleration[] a)
		{
			return f[1].DecomposedForce[1].Y + f[1].DecomposedForce[2].Y;
		}
		private double Min3(L.TotalForce[] f, L.Mass[] m, L.Acceleration[] a)
		{
			return a[0].Y - a[1].X;
		}		
	}
}
